package com.tpvlog.im.gateway.tcp.common;

import io.netty.channel.socket.SocketChannel;
import redis.clients.jedis.Jedis;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Session管理组件
 */
public class SessionManager {
    /**
     * <客户端uid, 客户端连接>的映射
     */
    private Map<String, SocketChannel> uid2Channel = new ConcurrentHashMap<String, SocketChannel>();
    /**
     * <客户端地址，客户端uid>的映射
     */
    private ConcurrentHashMap<String, String> address2uid = new ConcurrentHashMap<String, String>();

    private SessionManager() {
    }

    public static SessionManager getInstance() {
        return SessionManagerHolder.sessionManager;
    }

    /**
     * 通过Channel获取uid
     *
     * @param socketChannel
     * @return
     */
    public String getUidByChannel(SocketChannel socketChannel) {
        String address = socketChannel.remoteAddress().getHostName() + ":" + socketChannel.remoteAddress().getPort();
        return address2uid.get(address);
    }

    /**
     * 添加一个已建立连接的客户端
     *
     * @param uid
     * @param socketChannel
     */
    public void addSession(String uid, SocketChannel socketChannel) {
        String address = socketChannel.remoteAddress().getHostName() + ":"
                + socketChannel.remoteAddress().getPort();
        address2uid.put(address, uid);
        uid2Channel.put(uid, socketChannel);
    }

    /**
     * 判断客户端连接是否存在
     *
     * @param uid
     * @return
     */
    public Boolean isConnected(String uid) {
        return uid2Channel.containsKey(uid);
    }

    /**
     * 根据用户id获取对应的客户端连接
     *
     * @param uid
     * @return
     */
    public SocketChannel getSession(String uid) {
        return uid2Channel.get(uid);
    }

    /**
     * 删除一个客户端的连接
     *
     * @param socketChannel
     */
    public void removeSession(SocketChannel socketChannel) {
        // 1.删除本地缓存的连接
        String channelId = socketChannel.remoteAddress().getHostName() + ":"
                + socketChannel.remoteAddress().getPort();
        String uid = address2uid.get(channelId);
        uid2Channel.remove(uid);
        address2uid.remove(channelId);

        // 2.删除Redis中缓存的连接
        JedisManager jedisManager = JedisManager.getInstance();
        Jedis jedis = jedisManager.getJedis();
        jedis.del("session_" + this.getUidByChannel(socketChannel));
    }

    private static class SessionManagerHolder {
        private static final SessionManager sessionManager = new SessionManager();
    }
}
